<template>
  <div class="select-tree-box" :style="selectStyle">
    <el-popover
      v-model="visible"
      placement="bottom"
      popper-class="custom-select-tree-popover"
      width="200"
      trigger="click"
    >
      <div class="tree-box">
        <el-tree
          ref="treeRef"
          :data="optionList"
          v-bind="attrConfig"
          :filter-node-method="filterNode"
          @check="handleCheck"
          @node-click="handleNodeClick"
        />
      </div>

      <el-input
        slot="reference"
        v-model="value"
        :class="{ 'selected-name': !visible && selectedName }"
        :placeholder="handlePlaceholder"
        :clearable="!!selectConfig.clearable"
        @input="handleInput"
        @clear="handleClear"
      >
        <i
          slot="suffix"
          :class="[
            'el-input__icon el-icon-arrow-up',
            visible ? 'up-arrow' : 'down-arrow'
          ]"
        />
      </el-input>
    </el-popover>
  </div>
</template>

<script>
export default {
  name: 'SelectTree',
  props: {
    // 筛选样式
    selectStyle: {
      type: Object,
      default: () => ({})
    },
    // 筛选配置
    selectConfig: {
      type: Object,
      default: () => ({})
    },
    // 筛选数据
    selectData: {
      type: Object,
      default: () => ({})
    },
    // 是否重置
    isReset: {
      type: Boolean,
      default: false
    },
    dynamicSelectData: {
      type: Object,
      default: () => {}
    }
  },
  data() {
    return {
      visible: false,
      value: null,
      filterText: '',
      selectedName: '',
      selectedCode: '',
      optionList: []
    }
  },
  computed: {
    // 属性配置
    attrConfig() {
      const config = {
        // 'node-key': 'id',
        'default-expanded-keys': [],
        'default-checked-keys': [],
        'show-checkbox': false,
        'default-expand-all': false,
        'highlight-current': true,
        props: { children: 'children', label: 'label' }
      }
      return Object.assign(config, this.selectData?.treeAttrConfig || {})
    },
    handlePlaceholder() {
      if (this.selectedName) {
        return this.selectedName
      }
      return this.selectConfig.placeholder || '请输入内容'
    }
  },
  watch: {
    'selectData.optionList': {
      handler(option) {
        if (option && option.length > 0) {
          this.optionList = option
          this.handlerDefault('init')
        }
      },
      deep: true,
      immediate: true
    },
    isReset() {
      this.handlerDefault('init')
    },
    filterText(val) {
      this.$refs.treeRef?.filter(val)
    },
    visible(val) {
      this.value = JSON.parse(JSON.stringify(val ? '' : this.selectedName))
    },
    dynamicSelectData: {
      handler(val) {
        if (val && Object.keys(val).length) {
          const { prop } = this.selectData
          for (const key in val) {
            if (Object.hasOwnProperty.call(val, key) && key === prop) {
              this.filterText = ''
              this.value = ''
              this.selectedName = ''
              this.selectedCode = val[key]
              // this.handlerSelectData(this.selectedCode)
            }
          }
        }
      },
      deep: true
    }
  },
  methods: {
    /**
     * 处理默认值
     */
    handlerDefault() {
      const { defaultConfig } = this.selectData
      this.filterText = ''
      this.value = ''
      this.selectedName = ''
      this.selectedCode = ''
      if (defaultConfig) {
        this.selectedCode = defaultConfig.value
      }
      if (this.selectedCode) {
        this.handlerSelectData(this.selectedCode, 'init')
      }
    },
    /**
     * 处理筛选
     * @param {*} val 数据
     * @param {*} type 类型
     */
    handlerSelectData(val, type) {
      const { prop } = this.selectData
      const obj = {}
      // selectConfig.multiple
      obj[prop] = this.selectedCode
      this.$emit('handlerSelectData', obj, type)
    },
    /**
     * 处理输入查询
     * @param {*} data 数据
     */
    handleInput() {
      this.filterText = this.value
    },
    /**
     * 处理输入查询
     * @param {*} data 数据
     */
    handleClear() {
      this.filterText = ''
      this.value = ''
      this.selectedName = ''
      this.selectedCode = ''
      this.handlerSelectData(this.selectedCode)
    },
    /**
     * 节点的显示过滤
     * @param {*} data 数据
     */
    filterNode(value, data) {
      const { props = {} } = this.attrConfig || {}
      if (!value) return true
      return data[props.label || 'label'].indexOf(value) !== -1
    },
    /**
     * 点击树节点
     * @param {*} data 数据
     */
    handleNodeClick(data) {
      const { props = {} } = this.attrConfig || {}
      this.selectedName = data[props.label || 'label']
      this.selectedCode = data[props.value || 'id']
      this.value = this.selectedName
      this.filterText = ''
      this.visible = false
      this.handlerSelectData(this.selectedCode)
    },
    /**
     * 选中
     * @param {*} node 数据
     * @param {*} data 数据
     */
    handleCheck(node, data) {
      // checkedKeys 选中的key
      // halfCheckedKeys 半选的key
      // this.$emit('handleCheck', { node, ...data || {}})
    }
  }
}
</script>

<style lang="scss">
.custom-select-tree-popover {
  max-height: 400px;
  overflow: auto;

  .el-tree-node__content {
    height: 34px;
  }
}
</style>

<style lang="scss" scoped>
.select-tree-box {
  width: 132px;

  ::v-deep .el-input {
    width: 100%;

    .el-icon-arrow-up {
      transform: rotateZ(180deg);
      transition: transform 0.3s;
      &.up-arrow {
        transform: rotateZ(0deg);
        transition: transform 0.3s;
      }
    }

    &.selected-name:focus,
    &.selected-name:hover {
      .el-icon-arrow-up {
        display: none;
      }
    }
  }
}
</style>
